#include "mem_mgr.h"
#include <stdlib.h>


int FreeAudioCache();
int FreeRecordCache();

#define AUDIO_BUF_SIZE (1024*1024)
#define RECORD_BUF_SIZE (2*1024*1024)
typedef struct StMemMgr {
    void *pmem;
    int size;
    void *pAudioBuf;
    int SizeAudio;
}StMemMgr;

typedef struct StMemLayout {
    char arr_record_cache[RECORD_BUF_SIZE];
    char data[0];
}StMemLayout;

struct StMemMgr gMemMgr;

struct HeapCB *my_heap=0;
void *psram_malloc (unsigned int size)
{

    if (my_heap==0){
        my_heap =Heap_FindHeap("PSRAM");
        if(my_heap==NULL){
            printf("M_FindHeapd  ERROR!\r\n");
            return NULL;
        }
    }
    return M_MallocHeap(size,my_heap,0);
}

void psram_free (void *p)
{
    return M_FreeHeap(p, my_heap);
}

int MemMgrInit()
{
    struct StMemMgr *pMemMgr = &gMemMgr;

    pMemMgr->pAudioBuf = psram_malloc (AUDIO_BUF_SIZE);
    if (pMemMgr->pAudioBuf == 0) {
        printf("info: psram_malloc audio buffer %d failed!\r\n", AUDIO_BUF_SIZE);
        return -1;
    }
    pMemMgr->SizeAudio = AUDIO_BUF_SIZE;

    pMemMgr->pmem = psram_malloc (SHARE_BUF_SIZE);
    if (pMemMgr->pmem == 0) {
        printf("info: psram_malloc share buffer %d failed!\r\n", SHARE_BUF_SIZE);
        return -1;
    }
    pMemMgr->size = SHARE_BUF_SIZE;

    printf("info: psram_malloc %d successfully!\r\n", SHARE_BUF_SIZE);
    return 0;
}

void *GetAudioLoopBufAddr()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pAudioBuf == 0) return 0;

    return pMemMgr->pAudioBuf;
}
int GetAudioLoopBufSize()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pAudioBuf == 0) return 0;

    return pMemMgr->SizeAudio;
}

void *GetRecordCacheAddr()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pmem == 0) return 0;
    if (pMemMgr->size < sizeof(struct StMemLayout)) {
        printf("error: pMemMgr->size[%d] < sizeof(struct StMemLayout)[%d], failed!\r\n", pMemMgr->size, sizeof(struct StMemLayout));
        return 0;
    }
    struct StMemLayout *pMemLayout = (struct StMemLayout *)pMemMgr->pmem;
    return pMemLayout->arr_record_cache;
}
int GetRecordCacheSize()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pmem == 0) return 0;
    if (pMemMgr->size < sizeof(struct StMemLayout)) {
        printf("error: pMemMgr->size[%d] < sizeof(struct StMemLayout)[%d], failed!\r\n", pMemMgr->size, sizeof(struct StMemLayout));
        return 0;
    }
    struct StMemLayout *pMemLayout = (struct StMemLayout *)pMemMgr->pmem;
    return sizeof(pMemLayout->arr_record_cache);
}

void *GetUpdateBufAddr()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pmem == 0) return 0;
    if (pMemMgr->size < sizeof(struct StMemLayout)) {
        printf("error: pMemMgr->size[%d] < sizeof(struct StMemLayout)[%d], failed!\r\n", pMemMgr->size, sizeof(struct StMemLayout));
        return 0;
    }
    //struct StMemLayout *pMemLayout = (struct StMemLayout *)pMemMgr->pmem;
    FreeAudioCache();
    FreeRecordCache();
    return pMemMgr->pmem;
}

int GetUpdateBufSize()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pmem == 0) return 0;
    FreeAudioCache();
    FreeRecordCache();
    return pMemMgr->size;
}

void *GetAudioCacheAddr()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pmem == 0) return 0;
    if (pMemMgr->size < sizeof(struct StMemLayout)) {
        printf("error: pMemMgr->size[%d] < sizeof(struct StMemLayout)[%d], failed!\r\n", pMemMgr->size, sizeof(struct StMemLayout));
        return 0;
    }
    struct StMemLayout *pMemLayout = (struct StMemLayout *)pMemMgr->pmem;
    return pMemLayout->data;
}

int GetAudioCacheSize()
{
    struct StMemMgr *pMemMgr = &gMemMgr;
    if (pMemMgr->pmem == 0) return 0;
    return pMemMgr->size-sizeof(struct StMemLayout);
}
